package com.lins.storedisk.oss;

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.lins.disk.common.APIException;
import com.lins.disk.common.AppCode;
import com.lins.disk.constant.SysParams;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;

/**
 * @Author linshuo
 * @Date 2023/12/6 16:37
 */
@Slf4j
@Component
public class OssUtil {

    @Autowired
    SysParams params;

    public OSS createOss(){
        return new OSSClientBuilder().build(
                params.getOssEndpoint(),
                params.getOssAccessKeyId(),
                params.getOssAccessKeySecret());
    }


    public void upload(String url, MultipartFile mf, File file){
        OSS oss = createOss();
        try {
            //构建上传文件请求
            PutObjectRequest request = new PutObjectRequest(params.getOssBucketName(),url.substring(1), file);
            String contentType = mf.getContentType();
            if ("text/plain".equals(contentType)){
                ObjectMetadata metadata = new ObjectMetadata();
                metadata.setContentType(contentType+";charset=utf-8");
                request.setMetadata(metadata);
            }
            oss.putObject(request);
        } catch (OSSException oe) {
            printOSSException(oe);
        } catch (ClientException ce) {
            printClientException(ce);
        } finally {
            if (oss != null) oss.shutdown();
        }
    }

    /**
     * 下载Object到本地文件，并保存到指定的本地路径中。如果指定的本地文件存在会覆盖，不存在则新建。
     * 如果未指定本地路径，则下载后的文件默认保存到示例程序所属项目对应本地路径中。
     **/
    public void download(String fileUrl,String fileLocalPath){
        OSS oss = createOss();
        try {
            //获取文件对象写入本地存储
            oss.getObject(new GetObjectRequest(params.getOssBucketName(), fileUrl.substring(1)), new File(fileLocalPath));
        } catch (OSSException oe) {
            printOSSException(oe);
        } catch (ClientException ce) {
            printClientException(ce);
        } finally {
            if (oss != null) {
                oss.shutdown();
            }
        }
    }

    public void rename(String oldUrl,String newUrl){
        String bucketName = params.getOssBucketName();
        OSS ossClient = createOss();
        try {
            CopyObjectResult result = ossClient.copyObject(
                    bucketName, oldUrl.substring(1),
                    bucketName, newUrl.substring(1));
            log.info("ETag: " + result.getETag() + " LastModified: " + result.getLastModified());
        } catch (OSSException oe) {
            printOSSException(oe);
        } catch (ClientException ce) {
            printClientException(ce);
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }

    private void printOSSException(OSSException oe){
        log.error("OSSException异常：请求被发送到了OSS,但由于某种原因被拒绝了，并给出了错误响应。");
        log.error("Error Message:" + oe.getErrorMessage());
        log.error("Error Code:" + oe.getErrorCode());
        log.error("Request ID:" + oe.getRequestId());
        log.error("Host ID:" + oe.getHostId());
        throw new APIException(AppCode.OSS_ERROR,oe.getErrorMessage());
    }
    private void printClientException(Exception ce){
        log.error("ClientException：客户端在试图与OSS通信时遇到了严重的内部问题，例如无法访问网络。");
        log.error("Error Message:" + ce.getMessage());
        throw new APIException(AppCode.OSS_ERROR,ce.getMessage());
    }

    private void printThrowable(Throwable te){
        log.error("Throwable可抛出的所有对象的根基类-大异常：OSS异常！");
        log.error("Error Message:" + te.getMessage());
        throw new APIException(AppCode.OSS_ERROR,te.getMessage());
    }


//    public static void download() throws com.aliyuncs.exceptions.ClientException {
//        // Endpoint以华东1（杭州）为例，其它Region请按实际情况填写。关于其他Region对应的Endpoint信息，请参见访问域名和数据中心。
//        String endpoint = "http://oss-cn-beijing.aliyuncs.com";
//        // 从环境变量中获取访问凭证。运行本代码示例之前，请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
////        EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
//        // 填写Bucket名称，例如examplebucket。
//        String bucketName = "offcn-ls";
//        // 填写Object完整路径，例如exampledir/exampleobject.txt。Object完整路径中不能包含Bucket名称。
//        String objectName = "home/001.txt"; //https://bucket.aoas.top/home/001.txt
//
//        // 创建OSSClient实例。
//        OSS ossClient = new OSSClientBuilder().build(endpoint, "LTAI5t9K65UhjeS2PH5MVtRy","yyUYDj6e1rZ13s140Z6Yq96pItXI5q");
//        try {
////            // ossObject包含文件所在的存储空间名称、文件名称、文件元信息以及一个输入流。
////            OSSObject ossObject = ossClient.getObject(bucketName, objectName);
////
////            // 读取文件内容。
////            System.out.println("Object content:");
////            BufferedReader reader = new BufferedReader(new InputStreamReader(ossObject.getObjectContent()));
////            while (true) {
////                String line = reader.readLine();
////                if (line == null) break;
////                System.out.println("\n" + line);
////            }
////            // 数据读取完成后，获取的流必须关闭，否则会造成连接泄漏，导致请求无连接可用，程序无法正常工作。
////            reader.close();
////            // ossObject对象使用完毕后必须关闭，否则会造成连接泄漏，导致请求无连接可用，程序无法正常工作。
////            ossObject.close();
//
//            String s = "E:\\User\\Desktop\\Desktop\\test\\test"+"/src/main/resources/static/fileDir"+"/"+objectName;
//
//            ossClient.getObject(new GetObjectRequest(bucketName,objectName),new File(s));
//
//
//        } catch (OSSException oe) {
//        } catch (Throwable ce) {
//        } finally {
//            if (ossClient != null) {
//                ossClient.shutdown();
//            }
//        }
//    }


    public static void main(String[] args) throws Exception{

//        download();

//        //REST连接 没有指定数据库
//        String jdbcUrl = "jdbc:TAOS-RS://d.aoas.top:6041?user=root&password=taosdata";
//        //属性
//        Properties connProps = new Properties();
//        //设置属性，开启批量拉取结果集，默认false逐行拉取
//        connProps.setProperty(TSDBDriver.PROPERTY_KEY_BATCH_LOAD, "true");
//        //从驱动管理 获取连接
//        Connection conn = DriverManager.getConnection(jdbcUrl, connProps);
//        System.out.println("Connected："+conn.toString());
//        conn.close();

//        Class.forName("com.taosdata.jdbc.rs.RestfulDriver");
////        String jdbcUrl = "jdbc:TAOS-RS://d.aoas.top:6041/test?user=root&password=taosdata"; //atabase not exist
//        String jdbcUrl = "jdbc:TAOS-RS://d.aoas.top:6041/power?user=root&password=taosdata";
//        Connection conn = DriverManager.getConnection(jdbcUrl);
//        System.out.println(conn.toString());

        //项目工作目录
//        String property = System.getProperty("user.dir");
//        System.out.println(property);
//        String s = "/src/main/resoources/static/fileDir/";
//        s = property+ s;
//        System.out.println(s);
//
//        File folder = new File(s);
//        if (!folder.isDirectory()){
//            //目录不存在则创建
//            folder.mkdirs();
//        }

//        File file = new File(folder, filename);


        //项目运行目录
//        String path = ResourceUtils.getURL("classpath:").getPath();
//        System.out.println(path);

        //E:\User\Desktop\Desktop\test\test\src\main\resources\static\fileDir\other
        //E:\User\Desktop\Desktop\test\test


    }


}
